#include "ApiFile.h"

namespace GPUCC
{
	ApiFile::ApiFile(const std::string& Path) : File(Path), m_File(INVALID_HANDLE_VALUE)
	{
	}

	ApiFile::~ApiFile()
	{
		this->Close();
	}

	bool ApiFile::Open(bool ReadOnly)
	{
		DWORD DesiredAccess = GENERIC_READ;

		if (!ReadOnly)
		{
			DesiredAccess |=  GENERIC_WRITE;
		}

		this->m_File = CreateFile(this->m_Path.c_str(), DesiredAccess, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

		return (this->m_File != INVALID_HANDLE_VALUE);
	}

	void ApiFile::Close()
	{
		if (this->m_File != INVALID_HANDLE_VALUE)
		{
			CloseHandle(this->m_File);

			this->m_File = INVALID_HANDLE_VALUE;
		}
	}

	bool ApiFile::IsOpen()
	{
		return (this->m_File != INVALID_HANDLE_VALUE);
	}

	bool ApiFile::ReadAll(unsigned char* Buffer, unsigned int BufferLength)
	{
		bool Result = false;

		if ((Buffer != NULL) && (this->IsOpen()))
		{
			unsigned int FileSize = this->GetSize();

			if (BufferLength >= FileSize)
			{
				DWORD BytesRead;

				if ((ReadFile(this->m_File, Buffer, FileSize, &BytesRead, NULL)) && (BytesRead == FileSize))
				{
					Result = true;
				}
			}
		}

		return (Result);
	}

	bool ApiFile::ReadAll(std::vector<unsigned char>& Buffer)
	{
		bool Result = false;

		if (this->IsOpen())
		{
			unsigned int FileSize = this->GetSize();

			if (Buffer.capacity() < FileSize)
			{
				Buffer.reserve(FileSize);
			}

			DWORD BytesRead;

			if ((ReadFile(this->m_File, Buffer.data(), FileSize, &BytesRead, NULL)) && (BytesRead == FileSize))
			{
				Result = true;
			}
		}

		return (Result);
	}

	unsigned int ApiFile::GetSizeInternal()
	{
		LARGE_INTEGER Size;
		unsigned int Result = FileDetails::MAX_FILE_SIZE;

		if (GetFileSizeEx(this->m_File, &Size))
		{
			if (Size.HighPart == 0)
			{
				Result = Size.LowPart;
			}
		}

		return (Result);
	}
}